﻿using System.Collections.Generic;
using System.Reflection;
using Microsoft.Scripting.Hosting;

namespace Eswat.IronPython
{
	/// <summary>
	/// Test runner for IronPython test scripts.
	/// </summary>
	public class IronPythonTestRunner : TestRunnerBase<object>
	{
		private const string EngineName = "IronPython";

		private ScriptRuntime _runtime;

		private ScriptEngine _engine;

		/// <summary>
		/// Called when [before test].
		/// </summary>
		/// <typeparam name="TTestContext">The type of the test context.</typeparam>
		/// <param name="testContext">The test context.</param>
		/// <param name="availableInMemoryAssemblies">The available in memory assemblies.</param>
		protected override void OnBeforeTest<TTestContext>(
			ITestContext<TTestContext> testContext,
			IEnumerable<Assembly> availableInMemoryAssemblies)
		{
			this._runtime = ScriptRuntime.CreateFromConfiguration();
			this._engine = this._runtime.GetEngine(EngineName);

			foreach (var assembly in availableInMemoryAssemblies)
			{
				this._runtime.LoadAssembly(assembly);
			}
		}

		/// <summary>
		/// Runs the test.
		/// </summary>
		/// <typeparam name="TTestContext">The type of the test context.</typeparam>
		/// <param name="testContext">The test context.</param>
		/// <returns>
		/// The test result.
		/// </returns>
		protected override object RunTest<TTestContext>(ITestContext<TTestContext> testContext)
		{
			var scope = this._engine.CreateScope();

			this._runtime.Globals.SetVariable("eswatTest", testContext);

			this._engine.Execute("import eswatTest", scope);

			var result = this._engine.Execute(testContext.Template, scope);

			return result;
		}
	}
}
